package com.gisterrier.client.components;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.TreeMap;

import com.common.shared.ClSelectionItem;
import com.common.shared.map.GisMapClickedObject;
import com.gisterrier.client.GisTerrier;
import com.gisterrier.shared.BuildingCustomer;
import com.gisterrier.shared.BuildingCustomerShort;
import com.gisterrier.shared.ClSelection;
import com.gisterrier.shared.ObjSelectionresult;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.ListGridEditEvent;
import com.smartgwt.client.types.ListGridFieldType;
import com.smartgwt.client.widgets.Button;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.SelectItem;
import com.smartgwt.client.widgets.form.fields.events.ChangedEvent;
import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;

public class PBuildingCustomer extends VLayout {
	private SelectItem siRegion;
	private SelectItem siSubRegion;
	private SelectItem siCity;
	private SelectItem siStreet;
	private SelectItem siZones;

	final LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();

	private ListGrid lgCustomes = new ListGrid();
	private TreeMap<String, BuildingCustomerShort> mapCust = new TreeMap<String, BuildingCustomerShort>();

	private boolean settingMyself = false;

	private long buildingId;

	public PBuildingCustomer() {
		map.put("-1", "--");
		setHeight100();
		setWidth100();
		this.setMembersMargin(20);
		DynamicForm form = new DynamicForm();

		form.setWidth100();
		// form.setBorder("1px solid red");
		form.setTitleAlign(Alignment.LEFT);

		siRegion = new SelectItem();
		siRegion.setTitle("Region");
		siRegion.setWidth("100%");

		siSubRegion = new SelectItem();
		siSubRegion.setTitle("Sub Region");
		siSubRegion.setWrapTitle(false);
		siSubRegion.setWidth("100%");

		siCity = new SelectItem();
		siCity.setTitle("City");
		siCity.setWidth(200);
		siCity.setWidth("100%");

		siZones = new SelectItem();
		siZones.setTitle("Zones");
		siZones.setWidth(200);
		siZones.setWidth("100%");

		siStreet = new SelectItem();
		siStreet.setTitle("Bill. Street");
		siStreet.setWidth("100%");
		form.setLayoutAlign(Alignment.LEFT);

		form.setLayoutAlign(Alignment.LEFT);

		form.setFields(siRegion, siSubRegion, siCity, siStreet, siZones);

		this.addMember(form);

		siSubRegion.setValueMap(map);
		siSubRegion.setValue("-1");
		siCity.setValueMap(map);
		siCity.setValue("-1");
		siStreet.setValueMap(map);
		siStreet.setValue("-1");
		siZones.setValueMap(map);
		siZones.setValue("-1");

		GisTerrier.gissTerrierService
				.getAllTopTypes(new AsyncCallback<TreeMap<Integer, ArrayList<ClSelectionItem>>>() {

					@Override
					public void onSuccess(
							TreeMap<Integer, ArrayList<ClSelectionItem>> result) {
						setSelectItems(siRegion,
								result.get(ClSelection.T_REGION));
					}

					@Override
					public void onFailure(Throwable caught) {
						// TODO Auto-generated method stub

					}
				});
		siRegion.addChangedHandler(new ChangedHandler() {
			@Override
			public void onChanged(ChangedEvent event) {
				if (settingMyself)
					return;
				long id = Long.parseLong(event.getValue().toString());
				// setZones(id, null, null, null);
				siZones.setValueMap(map);
				siZones.setValue("-1");
				setSubRegions(id);

			}

		});
		siSubRegion.addChangedHandler(new ChangedHandler() {
			@Override
			public void onChanged(ChangedEvent event) {
				if (settingMyself)
					return;
				long id = Long.parseLong(event.getValue().toString());
				// setZones(null, id, null, null);
				setCities(id);
				siZones.setValueMap(map);
				siZones.setValue("-1");

			}

		});
		siCity.addChangedHandler(new ChangedHandler() {
			@Override
			public void onChanged(ChangedEvent event) {
				if (settingMyself)
					return;
				long id = Long.parseLong(event.getValue().toString());
				// setZones(null, null, id, null);
				setStreets(id);
				siZones.setValueMap(map);
				siZones.setValue("-1");
			}

		});

		siStreet.addChangedHandler(new ChangedHandler() {
			@Override
			public void onChanged(ChangedEvent event) {
				if (settingMyself)
					return;
				long id = Long.parseLong(event.getValue().toString());
				setZones(null, null, null, id);
				// setStreets(id);

			}

		});

		HLayout dynamicForm = new HLayout();
		dynamicForm.setMembersMargin(10);

		Button bSearchCustomers = new Button("Search");
		bSearchCustomers.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				Object val = siStreet.getValue();
				if (val == null)
					return;
				try {
					long streetid = Long.parseLong(val.toString());
					searchForSubscribers(streetid);
				} catch (Exception e) {
					// TODO: handle exception
				}

			}
		});
		dynamicForm.setAlign(Alignment.RIGHT);
		dynamicForm.addMember(bSearchCustomers);
		dynamicForm.setAutoHeight();
		this.addMember(dynamicForm);

		lgCustomes = new ListGrid() {
			@Override
			protected String getCellCSSText(ListGridRecord record, int rowNum,
					int colNum) {
				Object val = record.getAttribute("was");
				try {
					if (Boolean.parseBoolean(val.toString())) {
						val = record.getAttribute("building");
						long bu = 0;
						try {
							if (Long.parseLong(val.toString()) == buildingId)
								return "color:green;";
						} catch (Exception e) {
							// TODO: handle exception
						}

						return "color:#d64949;";
					}

				} catch (Exception e) {
					// TODO: handle exception
				}

				return super.getCellCSSText(record, rowNum, colNum);
			}
		};
		lgCustomes.setWidth100();
		lgCustomes.setHeight100();

		ListGridField lgfCustId = new ListGridField("custId", "ID", 50);
		lgfCustId.setCanEdit(false);
		ListGridField lgfCustname = new ListGridField("custname", "ტიპი", 200);
		lgfCustname.setCanEdit(false);
		ListGridField lgfSelected = new ListGridField("Selected", "T", 20);
		lgfSelected.setType(ListGridFieldType.BOOLEAN);
		lgfSelected.setCanEdit(true);

		ListGridField lgfWas = new ListGridField("was", "T", 20);
		lgfSelected.setType(ListGridFieldType.BOOLEAN);
		lgfWas.setHidden(true);
		ListGridField lgfBuilding = new ListGridField("building", "T", 20);
		lgfBuilding.setType(ListGridFieldType.INTEGER);
		lgfBuilding.setHidden(true);

		ListGridField lgfSerial = new ListGridField("serial");
		lgfSerial.setCanEdit(false);
		lgfSerial.setHidden(true);
		lgCustomes.setFields(lgfSelected, lgfCustId, lgfCustname, lgfSerial,
				lgfWas);
		lgCustomes.setCanEdit(true);
		lgCustomes.setEditEvent(ListGridEditEvent.CLICK);
		lgCustomes.setEditByCell(true);
		dynamicForm = new HLayout();
		dynamicForm.setMembersMargin(10);
		dynamicForm.addMember(lgCustomes);
		this.addMember(dynamicForm);

		dynamicForm = new HLayout();
		dynamicForm.setMembersMargin(10);

		Button bApplyCustomers = new Button("Apply");
		bApplyCustomers.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				applyCustomers();
			}
		});
		dynamicForm.setAlign(Alignment.RIGHT);
		dynamicForm.addMember(bApplyCustomers);
		dynamicForm.setAutoHeight();
		this.addMember(dynamicForm);
	}

	private void applyCustomers() {
		ArrayList<BuildingCustomerShort> mapbuildCusts = new ArrayList<BuildingCustomerShort>();
		ListGridRecord[] lrs = lgCustomes.getRecords();
		for (ListGridRecord lr : lrs) {
			String serial = lr.getAttribute("serial");
			Boolean sel = lr.getAttributeAsBoolean("Selected");
			Boolean was = lr.getAttributeAsBoolean("was");

			if ((sel && !was) /* || !sel && was */) {
				BuildingCustomerShort bc1 = mapCust.get(serial);
				if (bc1 != null
						&& (bc1.getBuilding_id() == buildingId || bc1
								.getBuilding_id() <= 0)) {
					BuildingCustomerShort bc = new BuildingCustomerShort();
					bc.setBuilding_id(buildingId);
					bc.setCusid(bc1.getCusid());
					mapbuildCusts.add(bc);
				}

			}
		}
		GisTerrier.gissTerrierService.insertMap_Customer_to_Building(
				mapbuildCusts, new AsyncCallback<ArrayList<Long>>() {

					@Override
					public void onSuccess(ArrayList<Long> result) {
						MainPanel.mainPanel.searchContainer
								.buildingCustomersChanged();
						try {
							searchForSubscribers(Long.parseLong(siStreet
									.getValue().toString()));
						} catch (Exception e) {
							// TODO: handle exception
						}

					}

					@Override
					public void onFailure(Throwable caught) {
						// TODO Auto-generated method stub

					}
				});
	}

	private void searchForSubscribers(long streetid) {
		Long zone = null;
		try {
			zone = Long.parseLong(siZones.getValue().toString());
		} catch (Exception e) {
			// TODO: handle exception
		}

		GisTerrier.gissTerrierService.getCustomersForStreet(streetid, zone,
				new AsyncCallback<ArrayList<BuildingCustomerShort>>() {

					@Override
					public void onSuccess(
							ArrayList<BuildingCustomerShort> result) {
						setCustomers(result);
					}

					@Override
					public void onFailure(Throwable caught) {
						// TODO Auto-generated method stub

					}
				});
	}

	private void setSelectItems(SelectItem si, ArrayList<ClSelectionItem> items) {
		if (items == null) {
			items = new ArrayList<ClSelectionItem>();
		}
		LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
		map.put("-1", "--");
		for (ClSelectionItem item : items) {
			map.put(item.getId() + "", item.getValue());
		}
		si.setValueMap(map);
		si.setValue("-1");
	}

	private void setSubRegions(long id) {
		siSubRegion.setValueMap(map);
		siSubRegion.setValue("-1");
		siCity.setValueMap(map);
		siCity.setValue("-1");
		siStreet.setValueMap(map);
		siStreet.setValue("-1");

		if (id < 0)
			return;
		GisTerrier.gissTerrierService.getSubRegions(id,
				new AsyncCallback<ArrayList<ClSelectionItem>>() {

					@Override
					public void onSuccess(ArrayList<ClSelectionItem> result) {
						setSelectItems(siSubRegion, result);

					}

					@Override
					public void onFailure(Throwable caught) {
						// TODO Auto-generated method stub

					}
				});
	}

	private void setZones(Long regionId, Long subRegionId, Long cityId,
			Long streetid) {
		siZones.setValueMap(map);
		siZones.setValue("-1");
		if (!(regionId != null || subRegionId != null || cityId != null)) {
			return;
		}

		GisTerrier.gissTerrierService.getZones(regionId, subRegionId, cityId,
				streetid, new AsyncCallback<ArrayList<ClSelectionItem>>() {

					@Override
					public void onSuccess(ArrayList<ClSelectionItem> result) {
						setSelectItems(siZones, result);

					}

					@Override
					public void onFailure(Throwable caught) {
						// TODO Auto-generated method stub

					}
				});
	}

	private void setCities(long id) {
		siCity.setValueMap(map);
		siCity.setValue("-1");
		siStreet.setValueMap(map);
		siStreet.setValue("-1");

		if (id < 0)
			return;
		GisTerrier.gissTerrierService.getCities(id,
				new AsyncCallback<ArrayList<ClSelectionItem>>() {

					@Override
					public void onSuccess(ArrayList<ClSelectionItem> result) {
						setSelectItems(siCity, result);

					}

					@Override
					public void onFailure(Throwable caught) {
						// TODO Auto-generated method stub

					}
				});
	}

	private void setStreets(long id) {
		siStreet.setValueMap(map);
		siStreet.setValue("-1");

		if (id < 0)
			return;
		GisTerrier.gissTerrierService.getStreets(id,
				new AsyncCallback<ArrayList<ClSelectionItem>>() {

					@Override
					public void onSuccess(ArrayList<ClSelectionItem> result) {
						setSelectItems(siStreet, result);

					}

					@Override
					public void onFailure(Throwable caught) {
						// TODO Auto-generated method stub

					}
				});
	}

	private void setCustomers(ArrayList<BuildingCustomerShort> customerShorts) {
		if (customerShorts == null)
			customerShorts = new ArrayList<BuildingCustomerShort>();
		lgCustomes.setData(new ListGridRecord[] {});
		mapCust.clear();
		ArrayList<ListGridRecord> records = new ArrayList<ListGridRecord>();

		lgCustomes.setData(records.toArray(new ListGridRecord[] {}));
		for (BuildingCustomerShort cs : customerShorts) {
			String uId = HTMLPanel.createUniqueId();
			mapCust.put(uId, cs);
			ListGridRecord r = new ListGridRecord();
			r.setAttribute("custId", cs.getCusid());
			r.setAttribute("custname", cs.getCusname());
			r.setAttribute("building", cs.getBuilding_id());
			r.setAttribute("Selected",
					cs.getBuilding_id() > 0
							&& cs.getBuilding_id() == buildingId);
			r.setAttribute("was", cs.getBuilding_id() > 0);
			r.setAttribute("serial", uId);
			records.add(r);
		}
		lgCustomes.setData(records.toArray(new ListGridRecord[] {}));
	}

	public void setResult(BuildingCustomer bc, GisMapClickedObject clObj) {

		buildingId = clObj.getGid();

		TreeMap<Integer, ArrayList<ClSelectionItem>> result = bc
				.getAddressInfo();
		ObjSelectionresult selectionresult = bc.getSelectionresult();

		final long buildingId = clObj.getGid();
		final long raioni = clObj.getRaioni();
		final long regioni = clObj.getRegioni();
		final long cityid = selectionresult == null ? -1 : selectionresult
				.getCityid();
		final long streetid = selectionresult == null ? -1 : selectionresult
				.getStreetid();
		Object obj = siRegion.getValue();
		long _region = -1;
		try {
			_region = Long.parseLong(obj.toString());
		} catch (Exception e) {
			// TODO: handle exception
		}

		obj = siSubRegion.getValue();
		long _raioni = -1;
		try {
			_raioni = Long.parseLong(obj.toString());
		} catch (Exception e) {
			// TODO: handle exception
		}
		if (_raioni != raioni || _region != regioni) {
			setSelectItems(siRegion, result.get(ClSelection.T_REGION));
			siRegion.setValue(regioni + "");
			siRegion.disable();
			setSelectItems(siSubRegion, result.get(ClSelection.T_SUBREGION));
			siSubRegion.setValue(raioni + "");
			siSubRegion.disable();
			setSelectItems(siCity, result.get(ClSelection.T_CITY));
			setSelectItems(siStreet, result.get(ClSelection.T_STREET));
		}
		// siCity.setValue(cityid + "");
		// if (cityid <= 0)
		// siCity.enable();
		// else {
		// siCity.disable();
		// }
		//

		// siStreet.setValue(streetid + "");
		// if (streetid <= 0)
		// siStreet.enable();
		// else {
		// siStreet.disable();
		// }
		setCustomers(null);
	}

	// public void setSelectedMapObject(final GisMapClickedObject clObj) {
	// buildingId = clObj.getGid();
	// GisTerrier.gissTerrierService.getBuildingCustomer(clObj,
	// new AsyncCallback<BuildingCustomer>() {
	//
	// @Override
	// public void onSuccess(BuildingCustomer result) {
	// setResult(result, clObj);
	// }
	//
	// @Override
	// public void onFailure(Throwable caught) {
	// // TODO Auto-generated method stub
	//
	// }
	// });
	// }
}
